home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / mewin10s.zip / MSWEXEC.C < prev    next >
C/C++ Source or Header  |  1992-02-27  |  11KB  |  358 lines

  1. /* The routines in this file provide support for external program
  2.    execution under the Microsoft Windows environment on an IBM-PC or
  3.    compatible computer.
  4.  
  5.    Must be compiled with Borland C++ 2.0 or later version.
  6.  
  7.    It should not be compiled if the WINDOW_MSWIN symbol is not set */
  8.  
  9. #include    "estruct.h"
  10. #include    <stdio.h>
  11. #include    "eproto.h"
  12. #include    "edef.h"
  13. #include    "elang.h"
  14.  
  15. #include    "mswin.h"
  16.  
  17. extern char *getenv (char *);
  18.  
  19. /* local data */
  20. static HWND hPrgWnd;    /* window handle of the external program task */
  21.  
  22.  
  23. /* HandleTimer: checks the existence of the external program window */
  24. /* ===========                                                      */
  25.  
  26. static void pascal near HandleTimer (HWND hDlg)
  27.  
  28. /* This function uses a 200ms timer to check the existence of the window
  29.    indicated by hPrgWnd. When that window handle becomes invalid, it is
  30.    assumed that the external program has exited and the WAITFORPRG
  31.    dialog box is terminated with a TRUE result. If there is a problem
  32.    setting the timer, the dialog box is terminated with a FALSE result
  33.    after a message box announcing the problem has been displayed. */
  34. {
  35.     if (IsWindow (hPrgWnd)) {
  36.     while (!SetTimer (hDlg, 1, 200, NULL)) {
  37.         /* bad: problem setting the timer */
  38.         if (MessageBox (hDlg, TEXT337, NULL, MB_RETRYCANCEL) == IDCANCEL) {
  39.             /* "cannot monitor external program" */
  40.         EndDialog (hDlg, FALSE);    /* give up! */
  41.         return;
  42.         }
  43.         /* else: attempt a retry */
  44.     }
  45.     }
  46.     else {
  47.     EndDialog (hDlg, TRUE);
  48.     }
  49. } /* HandleTimer */
  50.  
  51. /* WAITFORPRGDlgProc:   dialog proc for WAITFORPRG dialog box */
  52. /* =================                                          */
  53. int EXPORT far pascal  WAITFORPRGDlgProc (HWND hDlg, WORD wMsg,
  54.                       WORD wParam, DWORD lParam)
  55. {
  56.     switch (wMsg) {
  57.     case WM_INITDIALOG:
  58.         SetWindowText (hDlg, PROGNAME);
  59.     HandleTimer (hDlg);
  60.     return TRUE;
  61.     case WM_TIMER:
  62.     HandleTimer (hDlg);
  63.     break;
  64.     case WM_COMMAND:
  65.     if (wParam == 2) {  /* Cancel */
  66.         KillTimer (hDlg, 1);
  67.         EndDialog (hDlg, FALSE);
  68.     }
  69.     break;
  70.     default:
  71.     return FALSE;
  72.     }
  73.     return FALSE;
  74. } /* WAITFORPRGDlgProc */
  75.  
  76. /* LaunchPrgEnumProc:   used by LaunchPrg */
  77. /* =================                      */
  78. BOOL EXPORT far pascal LaunchPrgEnumProc (HWND hWnd, DWORD lParam)
  79.  
  80. /* this function sets hPrgWnd when it finds a window that matches the
  81.    module instance handle passed in lParam */
  82. {
  83.     if (GetWindowWord (hWnd, GWW_HINSTANCE) == LOWORD(lParam)) {
  84.     hPrgWnd = hWnd;
  85.     return FALSE;   /* found it, stop enumerating */
  86.     }
  87.     return TRUE;
  88. } /* LaunchPrgEnumProc */
  89.  
  90. /* LaunchPrg:   launches and monitors an external program  */
  91. /* =========                                               */
  92.  
  93. static BOOL pascal near LaunchPrg (char *Cmd, BOOL DOSApp,
  94.                                    char *InFile, char *OutFile)
  95.  
  96. /* Returns TRUE if all went well, FALSE if wait cancelled and FAILED if
  97.    failed to launch.
  98.  
  99.    Cmd is the command string to launch.
  100.  
  101.    DOSApp is TRUE if the external program is a DOS program to be run
  102.    under a DOS shell. If DOSApp is FALSE, the program is launched
  103.    directly as a Windows application. In that case, the InFile parameter
  104.    is ignored, and the value of the OutFile parameter is used only to
  105.    determine if the program should be monitored. the string referenced
  106.    by OutFile is irrelevant.
  107.  
  108.    InFile is the name of the file to pipe into stdin (if NULL, nothing
  109.    is piped in)
  110.  
  111.    OutFile is the name of the file where stdout is expected to be
  112.    redirected. If it is NULL, stdout is not redirected and the LaunchPrg
  113.    return immediately after starting the DOS box.
  114.  
  115.    If OutFile is not NULL, the external program is monitored. LaunchPrg
  116.    returns only when the external program has terminated or the user has
  117.    cancelled the wait (in which case LaunchPrg returns FALSE). */
  118. {
  119.     char    FullCmd [256];
  120.     HANDLE  hModule;
  121.     FARPROC ProcInstance;
  122.     int     nCmdShow;
  123.  
  124.     if (SetWorkingDir () != 0) {
  125.         mlwrite (TEXT334);  /* "[No such directory]" */
  126.         return FALSE;
  127.     }
  128.     if (DOSApp) {
  129.         if (OutFile || !Cmd) {
  130.         GetProfileString (ProgName, "DOSExec", "",
  131.                   FullCmd, 256 - NFILEN);
  132.         }
  133.     else FullCmd[0] = '\0';
  134.     if (FullCmd[0] == '\0') {
  135.         GetProfileString (ProgName, "DOSBox", "command.com",
  136.                           FullCmd, 256 - NFILEN);
  137.         }
  138.     /* the DOSBox profileString should be the name of a PIF file for
  139.        command.com that specifies no arguments and no starting dir.
  140.        The DOSExec should be similar but specify "Close window on
  141.        exit" */
  142.     if (Cmd) {
  143.         if ((strlen (FullCmd) + strlen (Cmd) + 3) >= 256) return FALSE;
  144.         strcat (FullCmd, " /c");
  145.         strcat (FullCmd, Cmd);
  146.     }
  147.     if (InFile) {
  148.         if ((strlen (FullCmd) + strlen (InFile) + 2) >= 256) return FALSE;
  149.         strcat (FullCmd, " <");
  150.         strcat (FullCmd, InFile);
  151.     }
  152.     if (OutFile) {
  153.         if ((strlen (FullCmd) + strlen (OutFile) + 2) >= 256) return FALSE;
  154.         strcat (FullCmd, " >");
  155.         strcat (FullCmd, OutFile);
  156.     }
  157.     }
  158.     if (GetWinFlags () & WF_ENHANCED) {
  159.         if (OutFile) nCmdShow = SW_SHOWMINIMIZED;
  160.         else nCmdShow = SW_SHOWNORMAL;
  161.     }
  162.     else nCmdShow = SW_SHOWNORMAL;
  163.  
  164.     hModule = WinExec (DOSApp ? FullCmd : Cmd, nCmdShow);
  165.         /* here we GOoooo */
  166.  
  167.     if (hModule < 32) {
  168.         mlwrite (TEXT3);    /* "[Execution failed]" */
  169.         return FAILED;
  170.     }
  171.     if (!OutFile) return TRUE;  /* no need to synchronize */
  172.     hPrgWnd = 0;
  173.     ProcInstance = MakeProcInstance ((FARPROC)LaunchPrgEnumProc,
  174.                                      hEmacsInstance);
  175.     EnumWindows (ProcInstance, (DWORD)hModule);
  176.     FreeProcInstance (ProcInstance);
  177.     if (hPrgWnd != 0) {
  178.     /*-put up a dialog box to wait for the external program termination */
  179.     int     Result;
  180.  
  181.     ProcInstance = MakeProcInstance ((FARPROC)WAITFORPRGDlgProc,
  182.                                          hEmacsInstance);
  183.     Result = DialogBox (hEmacsInstance, "WAITFORPRG",
  184.                 hFrameWnd, ProcInstance);
  185.     FreeProcInstance (ProcInstance);
  186.     return Result;
  187.     }
  188.     else return TRUE;   /* we assume it has zipped past us! */
  189. } /* LaunchPrg */
  190.  
  191. /* spawncli:    launch DOS shell. Bound to ^X-C */
  192. /* ========                                     */
  193.  
  194. PASCAL spawncli (int f, int n)
  195. {
  196.     /*-don't allow this command if restricted */
  197.     if (restflag) return resterr();
  198.  
  199.     return LaunchPrg (NULL, TRUE, NULL, NULL);
  200. } /* spawncli */
  201.  
  202. /* spawn:   run a one-liner in a DOS box. Bound to ^X-! */
  203. /* =====                                                */
  204.  
  205. PASCAL spawn (int f, int n)
  206. {
  207.     char    Line[NLINE];
  208.     int     Result;
  209.  
  210.     /*-don't allow this command if restricted */
  211.     if (restflag) return resterr();
  212.  
  213.     if ((Result = mlreply ("!", Line, NLINE)) != TRUE) return Result;
  214.     return LaunchPrg (Line, TRUE, NULL, NULL);
  215. } /* spawn */
  216.  
  217. /* execprg: run another program with arguments. Bound to ^X-$ */
  218. /* =======                                                    */
  219.  
  220. PASCAL execprg (int f, int n)
  221. {
  222.     char    Line[NLINE];
  223.     int     Result;
  224.  
  225.     /*-don't allow this command if restricted */
  226.     if (restflag) return resterr();
  227.  
  228.     /*-get the program command line */
  229.     if (mlreply ("$", Line, NLINE) != TRUE) return FALSE;
  230.  
  231.     Result = LaunchPrg (Line, FALSE, NULL, f ? Line : NULL);
  232.     if (Result == FAILED) {
  233.         mlwrite (TEXT3);    /* "[Execution failed]" */
  234.     }
  235.     return Result;
  236. } /* execprg */
  237.  
  238. /* pipecmd: pipe a one-liner into a window. Bound to ^X-@ */
  239. /* =======                                                */
  240.  
  241. PASCAL pipecmd (int f, int n)
  242.  
  243. /* this function fills a buffer named "command" with the output of the
  244.    DOS one-liner. If the command buffer already exist, it is overwritten
  245.    only if it has not been changed */
  246. {
  247.     char    Line[NLINE];
  248.     char    OutFile[NFILEN];
  249.     static  char bname[] = "command";
  250.     BUFFER  *bp;
  251.     WINDOW  *wp;
  252.     int     Result;
  253.     int     bmode;
  254.  
  255.     /*-don't allow this command if restricted */
  256.     if (restflag) return resterr();
  257.  
  258.     /*-get the command to pipe-in */
  259.     if (mlreply ("@", Line, NLINE) != TRUE) return FALSE;
  260.  
  261.     /*-find the "command" buffer */
  262.     if ((bp = bfind (bname, FALSE, 0)) != NULL) {
  263.     /*-make sure the contents can safely be blown away */
  264.     if (bp->b_flag & BFCHG) {
  265.         if (mlyesno (TEXT32) != TRUE) return FALSE;
  266.         /* discard changes */
  267.     }
  268.     }
  269.     else if ((bp = bfind (bname, TRUE, 0)) == NULL) {
  270.     mlwrite (TEXT137);
  271.         /* cannot create buffer */
  272.         return FALSE;
  273.     }
  274.     GetTempFileName (0, "UE", 0, OutFile);
  275.     Result = LaunchPrg (Line, TRUE, NULL, OutFile);
  276.     if (Result == FAILED) {
  277.     mlwrite (TEXT3);
  278.         /* [execution failed] */
  279.     unlink (OutFile);
  280.     }
  281.     else {
  282.         if (Result == TRUE) {
  283.         BUFFER  *temp_bp;
  284.  
  285.         temp_bp = curbp;
  286.         swbuffer (bp);          /* make this buffer the current one */
  287.         bmode = bp->b_mode;
  288.         bp->b_mode &= ~(MDVIEW | BFCHG);
  289.         Result = readin (OutFile, FALSE);
  290.         bp->b_fname[0] = '\0';  /* clear file name */
  291.         if (Result == TRUE) {
  292.         bp->b_mode |= MDVIEW;   /* force VIEW mode */
  293.         lchange (WFMODE);       /* update all relevant mode lines */
  294.         bp->b_flag &= ~BFCHG;   /* remove by-product BFCHG flag */
  295.         }
  296.         else {
  297.         bp->b_mode = bmode;     /* restore mode */
  298.         swbuffer (temp_bp);
  299.         }
  300.         unlink (OutFile);
  301.         /* note that the file is not deleted if the wait was cancelled */
  302.     }
  303.     }
  304.     return Result;
  305. } /* pipecmd */
  306.  
  307. /* filter:  filter a buffer through a DOS box. Bound to ^X-# */
  308. /* ======                                                    */
  309.  
  310. PASCAL filter (int f, int n)
  311. {
  312.     char    Line[NLINE];
  313.     char    InFile[NFILEN];
  314.     char    OutFile[NFILEN];
  315.     char    fname[NFILEN];
  316.     BUFFER  *bp;
  317.     WINDOW  *wp;
  318.     int     Result;
  319.  
  320.     /*-don't allow this command if restricted */
  321.     if (restflag) return resterr();
  322.  
  323.     /*-get the filter command line */
  324.     if (mlreply ("#", Line, NLINE) != TRUE) return FALSE;
  325.  
  326.     bp = curbp;
  327.     strcpy (fname, bp->b_fname);
  328.     GetTempFileName (0, "UE", 0, InFile);
  329.     Result = writeout (InFile, "w");
  330.     if (Result != TRUE) {
  331.     mlwrite (TEXT2);
  332.         /* cannot write filter file */
  333.     }
  334.     else {
  335.         GetTempFileName (0, "UE", 0, OutFile);
  336.     Result = LaunchPrg (Line, TRUE, InFile, OutFile);
  337.         if (Result == FAILED) {
  338.         mlwrite (TEXT3);
  339.         /* [execution failed] */
  340.             unlink (OutFile);
  341.             unlink (InFile);
  342.         }
  343.     else {
  344.             if (Result == TRUE) {
  345.         Result = readin (OutFile, FALSE);
  346.         unlink (OutFile);
  347.         unlink (InFile);
  348.         }
  349.         /* note that he files are not deleted if the wait was cancelled */
  350.         if (Result == TRUE) {
  351.         lchange (WFMODE);   /* update all relevant mode lines */
  352.         }
  353.     }
  354.     }
  355.     strcpy (bp->b_fname, fname);    /* restore original file name */
  356.     return Result;
  357. } /* filter */
  358.